<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><link rel="stylesheet" type="text/css" href="style.css" /><script type="text/javascript" src="highlight.js"></script></head><body><pre><span class="hs-pragma">{-# LANGUAGE DataKinds, FlexibleInstances, FlexibleContexts, UndecidableInstances,
     KindSignatures, TypeFamilies, CPP #-}</span><span class="hs-cpp">

#if !defined(TESTING)
</span><span class="hs-cpp"># if __GLASGOW_HASKELL__ &gt;= 710
</span><span class="hs-pragma">{-# LANGUAGE Safe #-}</span><span class="hs-cpp">
# else
</span><span class="hs-pragma">{-# LANGUAGE Trustworthy #-}</span><span class="hs-cpp">
#endif
</span><span class="hs-cpp">#endif
</span><span>
</span><span id="line-12"></span><span class="hs-comment">-- | Unsatisfiable constraints for functions being removed.</span><span>
</span><span id="line-13"></span><span>
</span><span id="line-14"></span><span class="hs-keyword">module</span><span> </span><span class="hs-identifier">Utils.Containers.Internal.TypeError</span><span> </span><span class="hs-keyword">where</span><span>
</span><span id="line-15"></span><span class="hs-keyword">import</span><span> </span><span class="annot"><a href="../../base/src/GHC.TypeLits.html#"><span class="hs-identifier">GHC.TypeLits</span></a></span><span>
</span><span id="line-16"></span><span>
</span><span id="line-17"></span><span class="hs-comment">-- | The constraint @Whoops s@ is unsatisfiable for every 'Symbol' @s@.</span><span>
</span><span id="line-18"></span><span class="hs-comment">-- Under GHC 8.0 and above, trying to use a function with a @Whoops s@</span><span>
</span><span id="line-19"></span><span class="hs-comment">-- constraint will lead to a pretty type error explaining how to fix</span><span>
</span><span id="line-20"></span><span class="hs-comment">-- the problem. Under earlier GHC versions, it will produce an extremely</span><span>
</span><span id="line-21"></span><span class="hs-comment">-- ugly type error within which the desired message is buried.</span><span>
</span><span id="line-22"></span><span class="hs-comment">--</span><span>
</span><span id="line-23"></span><span class="hs-comment">-- ==== Example</span><span>
</span><span id="line-24"></span><span class="hs-comment">--</span><span>
</span><span id="line-25"></span><span class="hs-comment">-- @</span><span>
</span><span id="line-26"></span><span class="hs-comment">-- oldFunction :: Whoops &quot;oldFunction is gone now. Use newFunction.&quot;</span><span>
</span><span id="line-27"></span><span class="hs-comment">--             =&gt; Int -&gt; IntMap a -&gt; IntMap a</span><span>
</span><span id="line-28"></span><span class="hs-comment">-- @</span><span>
</span><span id="line-29"></span><span class="hs-keyword">class</span><span> </span><span id="Whoops"><span class="annot"><a href="Utils.Containers.Internal.TypeError.html#Whoops"><span class="hs-identifier hs-var">Whoops</span></a></span></span><span> </span><span class="hs-special">(</span><span id="local-6989586621679184222"><span class="annot"><a href="#local-6989586621679184222"><span class="hs-identifier hs-type">a</span></a></span></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="annot"><span class="hs-identifier hs-type">Symbol</span></span><span class="hs-special">)</span><span class="hs-cpp">

#if __GLASGOW_HASKELL__ &gt;= 800
</span><span id="local-6989586621679184221"><span class="hs-keyword">instance</span><span> </span><span class="annot"><a href="../../base/src/GHC.TypeLits.html#TypeError"><span class="hs-identifier hs-type">TypeError</span></a></span><span> </span><span class="hs-special">(</span><span class="hs-special">'</span><span class="annot"><a href="../../base/src/GHC.TypeLits.html#Text"><span class="hs-identifier hs-type">Text</span></a></span><span> </span><span class="annot"><a href="#local-6989586621679184221"><span class="hs-identifier hs-type">a</span></a></span><span class="hs-special">)</span><span> </span><span class="hs-glyph">=&gt;</span><span> </span><span class="annot"><a href="Utils.Containers.Internal.TypeError.html#Whoops"><span class="hs-identifier hs-type">Whoops</span></a></span><span> </span><span class="annot"><a href="#local-6989586621679184221"><span class="hs-identifier hs-type">a</span></a></span></span><span class="hs-cpp">
#endif
</span><span>
</span><span id="line-35"></span><span class="hs-comment">-- Why don't we just use</span><span>
</span><span id="line-36"></span><span class="hs-comment">--</span><span>
</span><span id="line-37"></span><span class="hs-comment">-- type Whoops a = TypeError ('Text a) ?</span><span>
</span><span id="line-38"></span><span class="hs-comment">--</span><span>
</span><span id="line-39"></span><span class="hs-comment">-- When GHC sees the type signature of oldFunction, it will see that it</span><span>
</span><span id="line-40"></span><span class="hs-comment">-- has an unsatisfiable constraint and reject it out of hand.</span><span>
</span><span id="line-41"></span><span class="hs-comment">--</span><span>
</span><span id="line-42"></span><span class="hs-comment">-- It seems possible to hack around that with a type family:</span><span>
</span><span id="line-43"></span><span class="hs-comment">--</span><span>
</span><span id="line-44"></span><span class="hs-comment">-- type family Whoops a where</span><span>
</span><span id="line-45"></span><span class="hs-comment">--   Whoops a = TypeError ('Text a)</span><span>
</span><span id="line-46"></span><span class="hs-comment">--</span><span>
</span><span id="line-47"></span><span class="hs-comment">-- but I don't really trust that to work reliably. What we actually</span><span>
</span><span id="line-48"></span><span class="hs-comment">-- do is pretty much guaranteed to work. Despite the fact that there</span><span>
</span><span id="line-49"></span><span class="hs-comment">-- is a totally polymorphic instance in scope, GHC will refrain from</span><span>
</span><span id="line-50"></span><span class="hs-comment">-- reducing the constraint because it knows someone could (theoretically)</span><span>
</span><span id="line-51"></span><span class="hs-comment">-- define an overlapping instance of Whoops. It doesn't commit to</span><span>
</span><span id="line-52"></span><span class="hs-comment">-- the polymorphic one until it has to, at the call site.</span><span>
</span><span id="line-53"></span></pre></body></html>